import java.awt.Color;
import java.awt.Dimension;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;

/**
 * Cette classe regroupe la majeur partie du jeu d'echecs d'Alice.
 * On y crée les joueurs avec leurs pièces et les cases des échiquiers.
 * 
 * On y gere aussi les déplacements (fonctions drag & drop), et les règles du jeu.
 * 
 * On gere également dans cette classe la lecture/écriture dans des fichiers pour les sauvegarde/chargement de partie.
 * 
 **/


public class Alice extends JPanel implements MouseMotionListener, MouseListener
{
	/*****Attributs*****/
	private static final long serialVersionUID = 1L;
	
	/*Dessin*/
	private int nb_l = 8,		/*Nombre de lignes de chaque grille*/
				nb_c = 8,		/*Nombre de colonnes de chaque grille*/
				h_l = 40,		/*Hauteur d'une ligne de la grille*/
				l_c = 40,		/*longeur d'une colonne de la grille*/
				x_1, y_1, 		/*Point d'origine de la grille de gauche (en haut ‚à gauche)*/
				x_2, y_2;		/*Point d'origine de la grille de droite (en haut ‚à gauche)*/
	
	private Point p1[][],		/*Tableau des points des cases de l'échiquier de gauche*/
				  p2[][];		/*Tableau des points des cases de l'échiquier de droite*/
	
	static private Point dim = 	new Point( 39, 39 );	/*Dimension d'une case*/
	
	/*Joueurs*/
	private Joueur _joueurs[] = new Joueur[2];
	private JoueurBlanc joueurB = new JoueurBlanc();	/*Joueur Blanc*/
	private JoueurNoir joueurN =  new JoueurNoir();	/*Joueur Noir*/
	private int _trait = 0;			/*Numéro du joueur (0 pour blanc, 1 pour noir) qui a la main*/
	
	/*Pièces*/
	private Piece piB[] = new Piece[16]; /*Tableau des Pieces du joueur Blanc*/
	private Piece piN[] = new Piece[16]; /*Tableau des Pieces du joueur Noir*/
	
	/*Interface Graphique*/	
	private JLayeredPane  layeredPane = new JLayeredPane(); /*Panel de l'interface de jeu*/
		
	/*Image des Pièces*/
	/*Blancs*/
	final ImageIcon pionB = createImageIcon("/images2/pionb.png");
	final ImageIcon tourB = createImageIcon("/images2/tourb.png");
	final ImageIcon fouB = createImageIcon("/images2/foub.png");
	final ImageIcon cavalierB = createImageIcon("/images2/cavalierb.png");
	final ImageIcon reineB = createImageIcon("/images2/dameb.png");
	final ImageIcon roiB = createImageIcon("/images2/roib.png");
	/*Noirs*/
	final ImageIcon pionN = createImageIcon("/images2/pionn.png");
	final ImageIcon tourN = createImageIcon("/images2/tourn.png");
	final ImageIcon fouN = createImageIcon("/images2/foun.png");
	final ImageIcon cavalierN = createImageIcon("/images2/cavaliern.png");
	final ImageIcon reineN = createImageIcon("/images2/damen.png");
	final ImageIcon roiN = createImageIcon("/images2/roin.png");
		
	/* variables pour le drag and drop*/
	private int echq = 0; // détermine l'échiquier dans lequel on clique
	private int coord_init_x;
	private int coord_init_y;
	private int ix_init;
	private int iy_init;
	private Piece ptmp;
	
	private Fenetre fTmp;						/*Attribut fenetre temporaire, nécéssaire pour la modification des messages utilisateur*/
	
	/*****Constructeur*****/
	public Alice(boolean save, Fenetre f)
	{
		fTmp = f;
		
		/*Cases et contours dessinés*/
		initGrille();

		/*Joueurs et leurs pièces crées et dessinés*/
		if (!save)
		{
			_joueurs[0] = joueurB;
			_joueurs[1] = joueurN;
			initJoueurs();
		}		
		
		this.setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
		layeredPane.setPreferredSize(new Dimension(400, 900));
		layeredPane.setBorder(BorderFactory.createLineBorder(Color.GRAY));
		
		this.add(layeredPane);
		
	}
	
    /*Retourne une ImageIcon, null si le chemin d'accès est invalide*/
    protected static ImageIcon createImageIcon(String path)
	{
        java.net.URL imgURL = Alice.class.getResource(path);
        if (imgURL != null) 
		{
        	
            return new ImageIcon(imgURL);
        } 
		else
		{
            System.err.println("Couldn't find file: " + path);
            return null;
        }
    }
    
    /*Création des contours des Echiquiers*/
    public void contoursEchiquiers()
    {
    	/*Echiquier de droite*/
    	createLigne(p1[0][0].x-3, p1[0][0].y-3, 3, 325);/*verticale gauche*/
    	createLigne(p1[0][7].x+39, p1[0][0].y-3, 3, 325);/*verticale droite*/
    	createLigne(p1[0][0].x-3, p1[0][0].y-3, 325, 3);/*horizontale haut*/
    	createLigne(p1[7][0].x-3, p1[7][0].y+39, 325, 3);/*horizontale bas*/

    	/*Echiquier de gauche*/
    	createLigne(p2[0][0].x-3, p2[0][0].y-3, 3, 325);/*verticale gauche*/
    	createLigne(p2[0][7].x+39, p2[0][0].y-3, 3, 325);/*verticale droite*/
    	createLigne(p2[0][0].x-3, p2[0][0].y-3, 325, 3);/*horizontale haut*/
    	createLigne(p2[7][0].x-3, p2[7][0].y+39, 325, 3);/*horizontale bas*/
    	
    }
    
    /*Création d'une ligne pour le contour des Echiquiers*/
    public void createLigne(int x, int y , int la, int lo)
    {
    	JLabel ligne = new JLabel();
    	ligne.setBounds(x, y, la, lo);
    	ligne.setOpaque(true);
    	ligne.setBackground(Color.getHSBColor(139,117,0));
    	layeredPane.add(ligne,new Integer(0),0);
    }
    
    /*Création d'une case de l'équiquier en mode graphique*/
	public void createCase (int x, int y, Color c)
	{
		JLabel Case = new JLabel();
		Case.setOpaque(true);
		Case.setBackground(c);
		Case.setBounds(x, y, dim.x, dim.y);
		layeredPane.add(Case, new Integer(0));
	}
	
	/*Initialisaton des points(haut/gauche) des cases des échiquiers*/
	public void initP()
	{
		for( int i = 0; i < nb_l; i++ )
			for( int k = 0; k < nb_c; k++ )
			{
				p1[i][k] = new Point( x_1 + k * l_c + 1, y_1 + i * h_l + 1);
				p2[i][k] = new Point( x_2 + k * l_c + 1, y_2 + i * h_l + 1);
			}				
	}
	
	/*Initialisaton des cases des échiquiers*/
	public void initC()
	{	
		for( int i = 0; i < nb_l; i++ )
			for( int k = 0; k < nb_c; k++ )
				if ((i+k)%2 == 0)	/*Astuce: si la somme des coordonnées de la case est pair, la case est Blanche, Noire sinon*/
				{
					createCase(p1[i][k].x, p1[i][k].y ,Color.WHITE);
					createCase(p2[i][k].x, p2[i][k].y ,Color.WHITE);
				}
				else
				{
					createCase(p1[i][k].x, p1[i][k].y ,Color.getHSBColor(230, 200, 200));
					createCase(p2[i][k].x, p2[i][k].y ,Color.getHSBColor(230, 200, 200));
				}
				
	}
	
	/*créer les grilles/cases/pièces des Joueurs et les initialiser*/
	public void initGrille()
	{	
		p1 = new Point[nb_l][nb_c];
		p2 = new Point[nb_l][nb_c];

		x_1 = 100;
		y_1 = 50;
		x_2 = 480;
		y_2 = 50;
		
		initP();
		initC();
		contoursEchiquiers();		
	}
	
	/*Initialisation et affichage des joueurs*/
	public void initJoueurs()
	{	
		initJoueurB();
		initJoueurN();
		afficherPiecesJoueurs(true);
	}
	
	/*Initialisation du joueur blanc*/
	public void initJoueurB()
	{
		boolean white=true;
		int n = 0;
		int y = 8;
		
		/*Remplissage du tableau de pièces du joueur blanc*/
		
		piB[n++]= new Tour(n,y,white,true);
		piB[n++]= new Cavalier(n,y,white,true);
		piB[n++]= new Fou(n,y,white,true);
		piB[n++]= new Reine(n,y,white,true);
		piB[n++]= new Roi(n,y,white,true);
		piB[n++]= new Fou(n,y,white,true);
		piB[n++]= new Cavalier(n,y,white,true);
		piB[n++]= new Tour(n,y,white,true);
			
		y--;
		for ( int x = 1; x <= 8; x++ )
			piB[n++] = new Pion(x,y,white,true);
		joueurB.setM_pieces(piB);
	}
	
	/*Initialisation du joueur noir*/
	public void initJoueurN()
	{
		boolean white=false;
		int n = 0;
		int y = 1;

		/*Remplissage du tableau de pièces du joueur noir*/
		
		piN[n++]= new Tour(n, y, white, true);
		piN[n++]= new Cavalier(n, y, white, true);
		piN[n++]= new Fou(n, y, white, true);
		piN[n++]= new Reine(n, y, white, true);
		piN[n++]= new Roi(n, y, white, true);
		piN[n++]= new Fou(n, y, white, true);
		piN[n++]= new Cavalier(n, y, white, true);
		piN[n++]= new Tour(n, y, white, true);
								
		y++;
		for ( int x = 1; x <= 8; x++ )
			piN[n++] = new Pion(x,y,white,true);
				
		joueurN.setM_pieces(piN);
	}
	
	
	/******** Sauvegarde ********/
		
	/*Sauvegarde des joueurs*/
	public void sauverPartie(String libelle) throws IOException
	{
		/*Création du répertoire de sauvegarde si celui ci n'existe pas déjà*/
		String RepUser = System.getProperty("user.dir");
		File f = new File(RepUser+"\\Save");
		f.mkdirs(); 
		
		/* Le fichier de sauvegarde de type Alice ou ".a" est vide
		 * On retrouve les 2 fichiers contenant les joueurs créés à l'aide du libellé du fichier "alice"
		 * 
		 * */
		sauverJoueurB(libelle);
		sauverJoueurN(libelle);
		
		File fichier= new File("\\Save\\"+libelle+".a");
	    
	    if(!fichier.exists())
		     fichier.createNewFile();
	    FileWriter fw = new FileWriter(fichier);
	    Integer myInt = new Integer(_trait);
	    char c = myInt.toString().charAt(0);
	    fw.write(c);
	    fw.close();
	    
	    fTmp.getError().setForeground(Color.GREEN);
		fTmp.getError().setText("Sauvegarde effectuée dans le fichier "+RepUser+"\\Save\\"+libelle+".a   : Allez y!");
	}
	
	/*Sauvegarde du joueur blanc*/
	public void sauverJoueurB(String libelle) throws IOException
	{
		     File fichier= new File("\\Save\\"+libelle+"B");
		     if(!fichier.exists())
		     	fichier.createNewFile();
		     fichier.setWritable(true); 
		     fichier.setReadable(true);
		     if (fichier.canWrite()) {
		       try {
		         ObjectOutputStream flotEcriture = 
		             new ObjectOutputStream(
		                new FileOutputStream(fichier));
		 
		         flotEcriture.writeObject(joueurB);
		         flotEcriture.close();
		       } catch (IOException e) {
		         System.out.println(" erreur :" + e.toString());
		       }   
		     } 	
	}
	
	/*Sauvegarde du joueur noir*/
	public void sauverJoueurN(String libelle) throws IOException
	{
		File fichier= new File("\\Save\\"+libelle+"N");
	     if(!fichier.exists())
		     	fichier.createNewFile();
	     fichier.setWritable(true); 
	     fichier.setReadable(true);
	     if (fichier.canWrite()) {
	       try {
	         ObjectOutputStream flotEcriture = 
	             new ObjectOutputStream(
	                new FileOutputStream(fichier));
	 
	         flotEcriture.writeObject(joueurN);
	         flotEcriture.close();
	       } catch (IOException e) {
	         System.out.println(" erreur :" + e.toString());
	       }   
	     } 	
	}
	
	/******** Chargement ********/
	
	/*Chargement des joueurs*/
	public void chargerPartie(String libelle, int trait)
	{
		/*Recherche des nom des fichiers de chaque joueur en fontion du nom du fichier "alice"*/
		String libB; /*Nom du fichier du joueur blanc*/
		String libN; /*Nom du fichier du joueur noir*/
	
		String lib = libelle.substring(0, libelle.length()-2);//stock le nom sans le .a
	    
	    libB = "\\Save\\"+lib+"B";
	    libN = "\\Save\\"+lib+"N";
		
	    /*Initialisation du plateau de jeu*/
	    _trait = trait;
		chargerJoueurB(libB);
		chargerJoueurN(libN);
		_joueurs[0] = joueurB;
		_joueurs[1] = joueurN;
		
		afficherPiecesJoueurs(false);
		
		fTmp.getJoueurJoue().setText("C'est au joueur "+get_trait_coul()+" de jouer");
		fTmp.getError().setForeground(Color.GREEN);
		fTmp.getError().setText("Chargement effectué ... Allez y!");
	}

	/*Chargement du joueur blanc*/
	public void chargerJoueurB(String libelle)
	{ 
		
	       File fichier= new File(libelle);
	       if (!fichier.canRead()) {
	         System.out.println(libelle+" est impossible à ouvrir");
	         System.exit(0);
	       }
	       try {
	         ObjectInputStream flotLecture = 
	               new ObjectInputStream(
	                  new FileInputStream(fichier));
	         joueurB = (JoueurBlanc) flotLecture.readObject();
	         flotLecture.close();	    
	       } catch (Exception e) {
	         System.out.println(" erreur :" +e.toString());
	       }    
	}
	
	/*Chargement du joueur noir*/
	public void chargerJoueurN(String libelle)
	{
		File fichier= new File(libelle);
	       if (!fichier.canRead()) {
	         System.out.println(libelle+" est impossible à ouvrir");
	         System.exit(0);
	       }
	       try {
	         ObjectInputStream flotLecture = 
	               new ObjectInputStream(
	                  new FileInputStream(fichier));
	         joueurN = (JoueurNoir) flotLecture.readObject();
	         flotLecture.close();	    
	       } catch (Exception e) {
	         System.out.println(" erreur :" +e.toString());
	       }    
	}
	
	
	/******** Get & Set ********/
	
	public JoueurBlanc getJoueurB() {
		return joueurB;
	}

	public void setJoueurB(JoueurBlanc joueurB) {
		this.joueurB = joueurB;
	}

	public JoueurNoir getJoueurN() {
		return joueurN;
	}

	public void setJoueurN(JoueurNoir joueurN) {
		this.joueurN = joueurN;
	}
	
	public int get_trait() {
		return _trait;
	}
	
	public String get_trait_coul()
	{
		if (_trait == 0)
			return "Blanc";
		else return "Noir";
	}
	
	public void set_trait(int trait) {
		_trait = trait;
	}
	
	public JLayeredPane getLayeredPane() {
		return layeredPane;
	}

	public void setLayeredPane(JLayeredPane layeredPane) {
		this.layeredPane = layeredPane;
	}
	
	/******** Affichage ********/
		
	public void afficherPiecesJoueurs(boolean init)
	{
		if (!init)
		{
			initC();
			contoursEchiquiers();
		}
		
		for (int i=0; i<16; i++)
		{
			Piece pieB = _joueurs[0].get_pieces_ind(i);
			Piece pieN = _joueurs[1].get_pieces_ind(i);

			char pieceb = pieB.getM_type().charAt(0);
			char piecen = pieN.getM_type().charAt(0);
			if(pieB.get_active())
			{
				switch ( pieceb )
				{
					case 'p': 
							JLabel pb = new JLabel(pionB);
							pb.setName("b");
							pb.addMouseListener(this);			// ajoute un mouselistener pour detecter le clic et le relachement
							pb.addMouseMotionListener(this); 	// ajoute un mousemotionlistener pour détecter le drag n drop 		
							layeredPane.add(pb, new Integer(2),0);
							if (init)
								pb.setBounds(p1[6][i-8].x, p1[6][i-8].y, pionB.getIconWidth(), pionB.getIconHeight());
							else 
							{
								if ( pieB.echiquierG() )
									pb.setBounds(p1[pieB.y()-1][pieB.x()-1].x, p1[pieB.y()-1][pieB.x()-1].y, pionB.getIconWidth(), pionB.getIconHeight());
								else pb.setBounds(p2[pieB.y()-1][pieB.x()-1].x, p2[pieB.y()-1][pieB.x()-1].y, pionB.getIconWidth(), pionB.getIconHeight());
							}
							break;
							
					case 't': 
							JLabel tb = new JLabel(tourB);
							tb.setName("b");
							tb.addMouseListener(this);
							tb.addMouseMotionListener(this);	
							layeredPane.add(tb,new Integer(2),0);
							if (init)
								tb.setBounds(p1[7][i].x, p1[7][i].y, tourB.getIconWidth(), tourB.getIconHeight());
							else 
							{
								if ( pieB.echiquierG() )
									tb.setBounds(p1[pieB.y()-1][pieB.x()-1].x, p1[pieB.y()-1][pieB.x()-1].y, tourB.getIconWidth(), tourB.getIconHeight());
								else tb.setBounds(p2[pieB.y()-1][pieB.x()-1].x, p2[pieB.y()-1][pieB.x()-1].y, tourB.getIconWidth(), tourB.getIconHeight());
							}
							break;
							
					case 'f': 
							JLabel fb = new JLabel(fouB);
							fb.setName("b");
							fb.addMouseListener(this);
							fb.addMouseMotionListener(this); 		
							layeredPane.add(fb,new Integer(2),0);
							if (init)
								fb.setBounds(p1[7][i].x, p1[7][i].y, fouB.getIconWidth(), fouB.getIconHeight());
							else
							{
								if ( pieB.echiquierG() )
									fb.setBounds(p1[pieB.y()-1][pieB.x()-1].x, p1[pieB.y()-1][pieB.x()-1].y, fouB.getIconWidth(), fouB.getIconHeight());
								else fb.setBounds(p2[pieB.y()-1][pieB.x()-1].x, p2[pieB.y()-1][pieB.x()-1].y, fouB.getIconWidth(), fouB.getIconHeight());
							}
							break;
							
					case 'r': 
							JLabel rb = new JLabel(reineB);
							rb.setName("b");
							rb.addMouseListener(this);
							rb.addMouseMotionListener(this); 		
							layeredPane.add(rb,new Integer(2),0);
							if (init)
								rb.setBounds(p1[7][i].x, p1[7][i].y, reineB.getIconWidth(), reineB.getIconHeight());
							else 
							{
								if ( pieB.echiquierG() )
									rb.setBounds(p1[pieB.y()-1][pieB.x()-1].x, p1[pieB.y()-1][pieB.x()-1].y, reineB.getIconWidth(), reineB.getIconHeight());
								else
									rb.setBounds(p2[pieB.y()-1][pieB.x()-1].x, p2[pieB.y()-1][pieB.x()-1].y, reineB.getIconWidth(), reineB.getIconHeight());
							}
							break;
							
					case 'R': 
							JLabel Rb = new JLabel(roiB);
							Rb.setName("b");
							Rb.addMouseListener(this);
							Rb.addMouseMotionListener(this); 		
							layeredPane.add(Rb,new Integer(2),0);
							if (init)
								Rb.setBounds(p1[7][i].x, p1[7][i].y, roiB.getIconWidth(), roiB.getIconHeight());
							else 
							{
								if ( pieB.echiquierG() )
									Rb.setBounds(p1[pieB.y()-1][pieB.x()-1].x, p1[pieB.y()-1][pieB.x()-1].y, roiB.getIconWidth(), roiB.getIconHeight());
								else Rb.setBounds(p2[pieB.y()-1][pieB.x()-1].x, p2[pieB.y()-1][pieB.x()-1].y, roiB.getIconWidth(), roiB.getIconHeight());
							}
							break;
							
					case 'c': 
							JLabel cb = new JLabel(cavalierB);
							cb.setName("b");
							cb.addMouseListener(this);
							cb.addMouseMotionListener(this);  		
							layeredPane.add(cb,new Integer(2),0);
							if (init)
								cb.setBounds(p1[7][i].x, p1[7][i].y, cavalierB.getIconWidth(), cavalierB.getIconHeight());
							else 
							{
								if ( pieB.echiquierG() )
									cb.setBounds(p1[pieB.y()-1][pieB.x()-1].x, p1[pieB.y()-1][pieB.x()-1].y, cavalierB.getIconWidth(), cavalierB.getIconHeight());
								else cb.setBounds(p2[pieB.y()-1][pieB.x()-1].x, p2[pieB.y()-1][pieB.x()-1].y, cavalierB.getIconWidth(), cavalierB.getIconHeight());
							}
							break;
				}
			}
			if(pieN.get_active())
			{
				switch ( piecen )
				{
					case 'p':
							JLabel pn = new JLabel(pionN);
							pn.setName("n");
							pn.addMouseListener(this);
							pn.addMouseMotionListener(this);  		
							layeredPane.add(pn,new Integer(2),0);
							if (init)
								pn.setBounds(p1[1][i-8].x, p1[1][i-8].y, pionN.getIconWidth(), pionN.getIconHeight());
							else
							{
								if ( pieN.echiquierG() )
									pn.setBounds(p1[pieN.y()-1][pieN.x()-1].x, p1[pieN.y()-1][pieN.x()-1].y, pionN.getIconWidth(), pionN.getIconHeight());
								else pn.setBounds(p2[pieN.y()-1][pieN.x()-1].x, p2[pieN.y()-1][pieN.x()-1].y, pionN.getIconWidth(), pionN.getIconHeight());
							}
							break;
							
					case 't': 
							JLabel tn = new JLabel(tourN);
							tn.setName("n");
							tn.addMouseListener(this);
							tn.addMouseMotionListener(this);  		
							layeredPane.add(tn,new Integer(2),0);
							if (init)
								tn.setBounds(p1[0][i].x, p1[0][i].y, tourN.getIconWidth(), tourN.getIconHeight());
							else {
								if ( pieN.echiquierG() )
									tn.setBounds(p1[pieN.y()-1][pieN.x()-1].x, p1[pieN.y()-1][pieN.x()-1].y, tourN.getIconWidth(), tourN.getIconHeight());
								else tn.setBounds(p2[pieN.y()-1][pieN.x()-1].x, p2[pieN.y()-1][pieN.x()-1].y, tourN.getIconWidth(), tourN.getIconHeight());
							}
							break;
							
					case 'f': 
							JLabel fn = new JLabel(fouN);
							fn.setName("n");
							fn.addMouseListener(this);
							fn.addMouseMotionListener(this);  		
							layeredPane.add(fn,new Integer(2),0);
							if (init)
								fn.setBounds(p1[0][i].x, p1[0][i].y, fouN.getIconWidth(), fouN.getIconHeight());
							else {
								if ( pieN.echiquierG() )
									fn.setBounds(p1[pieN.y()-1][pieN.x()-1].x, p1[pieN.y()-1][pieN.x()-1].y, fouN.getIconWidth(), fouN.getIconHeight());
								else fn.setBounds(p2[pieN.y()-1][pieN.x()-1].x, p2[pieN.y()-1][pieN.x()-1].y, fouN.getIconWidth(), fouN.getIconHeight());
							}
							break;
							
					case 'r': 
							JLabel rn = new JLabel(reineN);
							rn.setName("n");
							rn.addMouseListener(this);
							rn.addMouseMotionListener(this);  		
							layeredPane.add(rn,new Integer(2),0);
							if (init)
								rn.setBounds(p1[0][i].x, p1[0][i].y, reineN.getIconWidth(), reineN.getIconHeight());
							else
							{
								if ( pieN.echiquierG() )
									rn.setBounds(p1[pieN.y()-1][pieN.x()-1].x, p1[pieN.y()-1][pieN.x()-1].y, reineN.getIconWidth(), reineN.getIconHeight());
								else rn.setBounds(p2[pieN.y()-1][pieN.x()-1].x, p2[pieN.y()-1][pieN.x()-1].y, reineN.getIconWidth(), reineN.getIconHeight());
							}
							break;
							
					case 'R': 
							JLabel Rn = new JLabel(roiN);
							Rn.setName("n");
							Rn.addMouseListener(this);
							Rn.addMouseMotionListener(this);  		
							layeredPane.add(Rn,new Integer(2),0);
							if (init)
								Rn.setBounds(p1[0][i].x, p1[0][i].y, roiN.getIconWidth(), roiN.getIconHeight());
							else {
								if ( pieN.echiquierG() )
									Rn.setBounds(p1[pieN.y()-1][pieN.x()-1].x, p1[pieN.y()-1][pieN.x()-1].y, roiN.getIconWidth(), roiN.getIconHeight());
								else Rn.setBounds(p2[pieN.y()-1][pieN.x()-1].x, p2[pieN.y()-1][pieN.x()-1].y, roiN.getIconWidth(), roiN.getIconHeight());
							}
							break;
							
					case 'c': 
							JLabel cn = new JLabel(cavalierN);
							cn.setName("n");
							cn.addMouseListener(this);
							cn.addMouseMotionListener(this);  		
							layeredPane.add(cn,new Integer(2),0);
							if (init)
								cn.setBounds(p1[0][i].x, p1[0][i].y, cavalierN.getIconWidth(), cavalierN.getIconHeight());
							else {
								if ( pieN.echiquierG() )
									cn.setBounds(p1[pieN.y()-1][pieN.x()-1].x, p1[pieN.y()-1][pieN.x()-1].y, cavalierN.getIconWidth(), cavalierN.getIconHeight());
								else cn.setBounds(p2[pieN.y()-1][pieN.x()-1].x, p2[pieN.y()-1][pieN.x()-1].y, cavalierN.getIconWidth(), cavalierN.getIconHeight());
							}
							break;
				}
			}
		}
	}
	
	/******** Fonctions utiles ********/
	
	/*Indique si une pièce active occupe la postion (x,y)*/
	/*public int position_occupee(int x, int y)
	{
		
	  for (int i=0; i<16; i++)
	    {
			  if ((_joueurs[0].get_pieces_ind(i).get_active()) || (_joueurs[1].get_pieces_ind(i).get_active()))
			  {
				  if ( (_joueurs[0].get_pieces_ind(i).x() == x) && (_joueurs[0].get_pieces_ind(i).y() == y ))
				  {
		    		  return 0;
				  }
				  if ( (_joueurs[1].get_pieces_ind(i).x() == x) && (_joueurs[1].get_pieces_ind(i).y() == y ))
				  {
		    		  return 1;
				  }
			  }
	    }
	  return -1;
	}*/
	
	/*Indique si une pièce active occupe la postion (x,y), selon l'échiquier spécifié*/
	public int position_occupee(int x, int y, boolean echiquierG)
	{
	  for (int i=0; i<16; i++)
	    {
		  /*Si piece sur l'échiquier de la piece*/
		  if ((_joueurs[0].get_pieces_ind(i).echiquierG()==echiquierG ) || (_joueurs[1].get_pieces_ind(i).echiquierG()==echiquierG))
			  if ((_joueurs[0].get_pieces_ind(i).get_active()) || (_joueurs[1].get_pieces_ind(i).get_active()))
			  {
				  if ( (_joueurs[0].get_pieces_ind(i).x() == x) && (_joueurs[0].get_pieces_ind(i).y() == y ))
				  {
		    		  return 0;
				  }
				  if ( (_joueurs[1].get_pieces_ind(i).x() == x) && (_joueurs[1].get_pieces_ind(i).y() == y ))
				  {
		    		  return 1;
				  }
			  }
	    }
	  return -1;
	}
	
	/*Change le trait : 0 ou 1*/
	public void change_joueur()
	{
	  _trait = (_trait+1)%2;	  
	}
	
	/*retourne la pièce située aux coordonées x,y*/
	public int recherche_indice_piece( int x, int y )
	{
	  for (int i=0; i<16; i++)
	    {
	      if (_joueurs[_trait].get_pieces_ind(i).x() == x && _joueurs[_trait].get_pieces_ind(i).y() == y)
	    	  return i;
	    }
	  return -1;
	}
	
	/******** Règes du jeu - Déplacement ********/
	
	/*Déplacer une pièce*/
	public boolean deplacer_piece(Piece pie, int initX, int initY, int finaleX, int finaleY)
	{
		boolean b = false;
		boolean echiquierG = _joueurs[_trait].get_piece(initX+1, initY+1).echiquierG();
		
		if ( pie.get_active() )
	    {
	    	  char piece = pie.getM_type().charAt(0);
	    	  
	    	  /*Si le roi est en echec avant de jouer*/
	    	  if (echecPossible(echiquierG))
	    	  { 
	    		  fTmp.getError().setForeground(Color.ORANGE); fTmp.getError().setText("Echec au roi!");
	    	  }
	    	  
/*
	    	  if (echecPossible(echiquierG))
	    	  {
	    		  b = false;
	    		  fTmp.getError().setForeground(Color.RED);
	    		  fTmp.getError().setText("Vous ne pouvez pas bouger cette Pièce : Echec au roi!");
	    	  }
	    	  else 
	    	  {*/
	    		  switch ( piece )
		    	  {
		    	  	case 'p': b = deplace_pion(initX, initY, finaleX, finaleY, echiquierG, true);
		    	  		break;
		    	  		
		    	  	case 't': b = deplace_tour(initX, initY, finaleX, finaleY ,echiquierG ,true);
		    	  		break;
		    	  		
		    	  	case 'f': b = deplace_fou(initX, initY, finaleX, finaleY, echiquierG, true);
		    	  		break;
		    	  		
		    	  	case 'r': b = deplace_reine(initX, initY, finaleX, finaleY, echiquierG, true);
		    	  		break;
		    	  	
		    	  	case 'c': b = deplace_cavalier(initX, initY, finaleX, finaleY, echiquierG, true);
		    	  		break;
		    	  }
	    	  //}
	    	  
	    	  System.out.println(_joueurs[1].get_pieces_ind(11));
	    	  if (piece == 'R') 
	    		  b = deplace_roi(initX, initY, finaleX, finaleY, echiquierG, true);
	    	  /*else if (echecPossible())
	    		  	if(b==false)
	    		  	{ fTmp.getError().setForeground(Color.ORANGE); fTmp.getError().setText("Echec et mat!"); }
	    */
	    }
		System.out.println("b="+b);
		testFinDePartie();
	   return b;
	}
	
	public boolean echecPossible(boolean echiquierG)
	{
		/*position du roi du joueur qui joue*/
		int posRX = _joueurs[_trait].get_pieces_ind(4).x();
		int posRY = _joueurs[_trait].get_pieces_ind(4).y();
		boolean echiquierGR = _joueurs[_trait].get_pieces_ind(5).echiquierG();
		
		System.out.println("x du roi "+this.get_trait_coul()+" : "+posRX);
		System.out.println("y du roi "+this.get_trait_coul()+" : "+posRY);
		
		//System.out.println("echiquier G du roi "+this.get_trait_coul()+" : "+echiquierG);
		this.change_joueur();
		
		
		
		System.out.println("trait : "+this.get_trait_coul());
		
		/*On teste tous les déplacements possibles des pièces adverse sur le même échiquier que le roi du joueur qui joue*/
		for (int i=0; i<16 ; i++)
			if (_joueurs[_trait].get_pieces_ind(i).echiquierG()==echiquierGR)
				if (deplacer_piece_fictif(_joueurs[_trait].get_pieces_ind(i), _joueurs[_trait].get_pieces_ind(i).x(), _joueurs[_trait].get_pieces_ind(i).y(), posRX, posRY, echiquierGR))
				{/*si echec au roi*/
					
					this.change_joueur();
					return true;
				}
					
		
		/*
		for (int i=0; i<16 ; i++)
			if (_joueurs[(_trait+1)%2].get_pieces_ind(i).echiquierG()==echiquierG)
				if (deplacer_piece_fictif(_joueurs[(_trait+1)%2].get_pieces_ind(i), _joueurs[(_trait+1)%2].get_pieces_ind(i).x(), _joueurs[(_trait+1)%2].get_pieces_ind(i).y(), posRX, posRY))
					return true;
		*/
		this.change_joueur();
		return false;
	}
	
	public boolean deplacer_piece_fictif(Piece pie, int initX, int initY, int finaleX, int finaleY, boolean echiquierG)
	{
		boolean b = false;
		System.out.println("depl fictif");
		
		if ( pie.get_active() )
	    {
	    	  char piece = pie.getM_type().charAt(0);
	    	  switch ( piece )
	    	  {
	    	  	case 'p': b = deplace_pion(initX, initY, finaleX, finaleY, echiquierG, false);
    	  		break;
    	  		
	    	  	case 't': b = deplace_tour(initX, initY, finaleX, finaleY ,echiquierG ,false);
	    	  		break;
	    	  		
	    	  	case 'f': b = deplace_fou(initX, initY, finaleX, finaleY, echiquierG, false);
	    	  		break;
	    	  		
	    	  	case 'r': b = deplace_reine(initX, initY, finaleX, finaleY, echiquierG, false);
	    	  		break;
	    	  	
	    	  	//case 'R': b = deplace_roi(initX, initY, finaleX, finaleY, echiquierG, false);
	    	  	//	break;
	    	  	
	    	  	case 'c': b = deplace_cavalier(initX, initY, finaleX, finaleY, echiquierG, false);
	    	  		break;
	    	  }
	    }	
	   return b;
	}
		
	public void redessiner()
	{
		layeredPane.removeAll();
		afficherPiecesJoueurs(false);
		layeredPane.repaint();
	}
	
	public void retourEchec(int fx, int fy, int ix, int iy )
	{
		_joueurs[_trait].set_pieces(recherche_indice_piece(fx +1, fy +1), ix +1, iy +1);
		fTmp.getError().setForeground(Color.RED);
		fTmp.getError().setText("Vous ne pouvez pas bouger cette Pièce : Echec au roi!");
	}
	
	public void testFinDePartie()
	{
		if(!_joueurs[1].get_pieces_ind(4).get_active() == true)
			new FinDePartie(this,fTmp,"Blanc");
		if(!_joueurs[0].get_pieces_ind(4).get_active() == true)
			new FinDePartie(this,fTmp,"Noir");
	}
	
	/* ------------------------------ PION ------------------------------ */

	public boolean deplace_pion(int initX, int initY, int finaleX, int finaleY, boolean echiquierG, boolean depl)
	{	
	  int diff_a = Math.abs(finaleX - initX);  // différence a plat
	  int diff_o = Math.abs(finaleY - initY);  // difference en hauteur
	  
	  if(_trait == 0 && (finaleY - initY) > 0) return false;
	  if(_trait == 1 && (finaleY - initY) < 0) return false;
	  
	  boolean echRoi = _joueurs[_trait].get_pieces_ind(5).echiquierG();
	  
	  if ( diff_a == 0 ) // deplacement vertical
	  {
		  if ((diff_o == 1) || (diff_o == 2))
		  {
			  if (diff_o == 2) // déplacement vertical de 2 cases
			  { 
				  if (initY == 1 || initY == 6) // position horizontale initiale
				  {
					  if(position_occupee(finaleX+1, finaleY+1, echiquierG ) != -1) //Si une pièce occupe la position finale
					  { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Une pièce occupee cette position !");} }
					  else	/*Déplacement de 2 cases*/
					  {
						  if (depl)
		    			  {
							  _joueurs[_trait].set_pieces(recherche_indice_piece(initX +1, initY +1), finaleX +1, finaleY +1);
							  System.out.println("Déplac av ech");
							  if (echecPossible(echRoi))
							  {
								  System.out.println("echec");
								  retourEchec(finaleX, finaleY, initX, initY);
								  return false;
							  }
							  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
							  redessiner();
							  change_joueur();
		    			  }
						  return true;
					  }
				  }
				  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Le pion n'est pas dans sa position initiale !"); }}
			  }
			  else
			  {
				  if(position_occupee(finaleX+1, finaleY+1, echiquierG ) != -1) //Si une pièce occupe la position finale
				  { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Une pièce occupe cette position !"); }}
				  else
				  {
					  if (depl)
	    			  {
						  if (_joueurs[_trait].get_piece(initX+1, initY+1).pionPromu(finaleY+1))
						  {
							  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
							  System.out.println("Déplac av ech");
							  if (echecPossible(echRoi))
							  {
								  System.out.println("echec");
								  retourEchec(finaleX, finaleY, initX, initY);
								  return false;
							  }
							  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
							  redessiner();
							  PromotionFenetre p = new PromotionFenetre(_joueurs[_trait].isM_white(), this, _joueurs[_trait].get_piece(finaleX+1, finaleY+1), fTmp);
						  }
						  else 
						  {
							  _joueurs[_trait].set_pieces(recherche_indice_piece(initX +1, initY +1), finaleX +1, finaleY +1);
							  System.out.println("Déplac av ech");
							  if (echecPossible(echRoi))
							  {
								  System.out.println("echec");
								  retourEchec(finaleX, finaleY, initX, initY);
								  return false;
							  }
							  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
							  redessiner();
						  }
						  change_joueur();
	    			  }
					  return true;
				  }
			  }
		  }
		  else {if (depl){ fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Deplacement impossible !");} }
	  }
	  else
	  {
		  if (diff_a == 1)
		  {
			  if (position_occupee(finaleX + 1, finaleY + 1, echiquierG ) == _trait)
			  { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("une de vos pièces occupe cette position. Coup impossible !"); }}
			  else
			  {
				  if (position_occupee(finaleX + 1 , finaleY + 1, echiquierG ) == -1 )
				  {
					  { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Prise impossible (pas de pièces) !"); }}
				  }
				  else if (diff_a == 1 && diff_o == 1)
				  {
					  /*PRISE*/
					  if (_joueurs[_trait].get_piece(initX+1, initY+1).echiquierG() == _joueurs[(_trait+1)%2].get_piece(finaleX+1,finaleY+1).echiquierG())
					  {
						  if (depl)
						  {
							  _joueurs[(_trait+1)%2].get_piece(finaleX +1, finaleY +1).delete();
							  if (_joueurs[_trait].get_piece(initX+1, initY+1).pionPromu(finaleY+1))
							  {
								  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
								  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
								  redessiner();
								  System.out.println("avant");
								  PromotionFenetre p = new PromotionFenetre(_joueurs[_trait].isM_white(), this, _joueurs[_trait].get_piece(finaleX+1, finaleY+1), fTmp);
	  
							  }
							  else
								  {
								  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
								  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
								  redessiner();
								  }
							  change_joueur();
						  }
						  return true;
					  }
					  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Pour pouvoir prendre, il faut que les pièces soient sur le même échiquier");} }
				  }
				  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Le pion ne peut pas prendre aussi loin !"); }}
			  }
		  }
		  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Impossible de déplacer le pion dans cette direction. Veuillez faire un coup valide."); }}
	  }
	  return false;
	}  
	
	
	


	/* ------------------------------ TOUR ------------------------------ */
	public boolean deplace_tour(int initX, int initY,int finaleX, int finaleY, boolean echiquierG, boolean depl/*, boolean protec*/)
	{
		int diff_a = finaleX - initX;  // différence a plat
		int diff_o = finaleY - initY;  // difference en hauteur
		System.out.println(diff_a);
		System.out.println(diff_o);
		
	  //valider deplacement tour 1er deplacement horizontal, 2eme depl vertical
	  if ( diff_a == 0 ^ diff_o == 0 )    
	    {
		  /*Deplacement possible*/
	      //si pas d'obstacle
	      if ( test_trajectoire_tour_ok(diff_a,diff_o,initX+1, initY+1, finaleX+1, finaleY+1, echiquierG) )
	      	{
	    	  /*test traj tour ok*/
	      	//test si place non libre et piece adverse
	    	  if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == _trait)
	    	  { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Une de vos pièces occupe déjà cette position. Coup impossible !"); }}
	    	  else
	    	  {
	    		  if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == -1 )
	    		  {
	    			  if (depl)
	    			  {
		    			  /*Deplacement TOUR*/
		    			  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
		    			  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
		    			  redessiner();
			    		  change_joueur();
	    			  }
		    		  return true;
	    		  }
	    		  else
	    		  {
	    			  if (echiquierG  == _joueurs[(_trait+1)%2].get_piece(finaleX+1,finaleY+1).echiquierG())
					  {
		    			  if (depl)
		    			  {
		    				  /*TOUR PREND*/
							  _joueurs[(_trait+1)%2].get_piece(finaleX +1, finaleY +1).delete();
			    			  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
			    			  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
			    			  redessiner();
				    		  change_joueur();
		    			  }
			    		  return true;
					  }
					  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Pour pouvoir prendre, il faut que les pièces soient sur le même échiquier"); }}
	    		  }  
	    	  }
	      	}
	      	else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("La tour ne peut pas sauter une piece");}}
	    	}
	  	else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Deplacement non valide"); }}
	  return false;
	}

	/*Teste la trajectoire de la tour, sur l'échiquier sur lequel se trouve la tour que l'on souhaite déplacer*/
	public boolean test_trajectoire_tour_ok(int diff_a, int diff_o,int initX, int initY,int finaleX, int finaleY, boolean echiquierG)
	{
	  int i;
	  boolean libre = true;
	  System.out.println("diff a:"+diff_a);
	  System.out.println("diff o:"+diff_o);
	  
	  if ( diff_a== 0 && diff_o > 0 )  //bas vertical
	    {
	      i=initY+1;
	      while ( i<=finaleY-1 && libre )
	      {
	    	  if ( position_occupee(initX,i,echiquierG) != -1)
	    	  {
	    		  libre = false;
	    	  }
	    	  else 
	    	  {
	    		  i++;
	    	  }
	      }  
	    }
	  else if( diff_o == 0 && diff_a > 0 )  //droite horizontal
	    {
	      i=initX+1;
	      while ( i<finaleX && libre )
	      {
	    	  if ( position_occupee(i,initY,echiquierG) != -1  )
	    	  {
	    		  libre=false;
	    	  }
	    	  else 
	    	  {
	    		  i++;
	    	  }
		  	}
	    }
	  else if( diff_a == 0 && diff_o < 0 )  //haut vertical
	    {
	      i=initY-1;
	      while ( i>finaleY && libre )
	      {
	    	  if  ( position_occupee(initX,i,echiquierG) != -1 )
	    	  {
	    		  libre=false;
	    	  }
	    	  else 
	    	  {
	    		  i--;
	    	  }	
	      }
	    }
	  else if( diff_o == 0 && diff_a < 0 )  //gauche horizontal
	    {
	      i=initX-1;
	      while ( i>finaleX && libre )
	      {
	    	  if  ( position_occupee(i,initY,echiquierG) != -1 )
	    	  {
	    		  libre=false;
	    	  }
	    	  else 
	    	  {
	    		  i--;
	    	  }
	      }
	    }
	  return libre;
	}
	
	/* ------------------------------ FOU ------------------------------ */
	public boolean deplace_fou(int initX, int initY,int finaleX, int finaleY, boolean echiquierG, boolean depl)
	{
		int diff_a = finaleX - initX;  // différence a plat
		int diff_o = finaleY - initY;  // difference en hauteur
	  	  
	  // (abs+ord)==0 -> abs et ord opposés : diag 0.7;7.0 
	  // (abs-ord)==0 -> abs et ord de m^ signe : diag 0.0;7.7 
	  if ( (diff_a+diff_o)==0 || (diff_a-diff_o)==0  ) 
	    {
	      if ( test_trajectoire_fou_ok(diff_a,diff_o,initX+1, initY+1, finaleX+1, finaleY+1,echiquierG) )
	      {
	    	  if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == _trait)
	    	  { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("une de vos pièces occupe cette position. Coup impossible !"); }}
	    	  else
	    	  {
	    		  if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == -1 )
	    		  {
	    			  System.out.println("dep fou...");
	    			  if (depl)
	    			  {
		    			  /*Deplacement FOU*/
		    			  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
		    			  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
		    			  redessiner();
			    		  change_joueur();
	    			  }
		    		  return true;
	    		  }
	    		  else
	    		  {
	    			  System.out.println("ech g r = piece adv pos?"+(echiquierG == _joueurs[(_trait+1)%2].get_piece(finaleX+1,finaleY+1).echiquierG()));
	    			  if (echiquierG == _joueurs[(_trait+1)%2].get_piece(finaleX+1,finaleY+1).echiquierG())
					  {
	    				  System.out.println("FOu prend?"+depl);
	    				  if (depl)
						  {
			    			  /*FOU PREND*/
							  _joueurs[(_trait+1)%2].get_piece(finaleX +1, finaleY +1).delete();
			    			  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
			    			  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
			    			  redessiner();
				    		  change_joueur();
						  }
	    				  return true;
					  }
					  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Pour pouvoir prendre, il faut que les pièces soient sur le même échiquier"); }}
	    		  }  
		    }
	     }
	     else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Le fou ne peut pas sauter de piece");}}
	    }
	  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Deplacement non valide"); }}
	  return false;
	}

	/*Teste la trajectoire de la tour, sur l'échiquier sur lequel se trouve la tour que l'on souhaite déplacer*/
	public boolean test_trajectoire_fou_ok (int diff_a, int diff_o,int initX, int initY,int finaleX, int finaleY, boolean echiquierG)
	{
	  boolean libre=true;
	  if ( diff_a > 0 && diff_o > 0 )  //bas droite
	    {
	      int i = 1;
	      while ( initX+i < finaleX && libre )
	      {
	    	  if ( position_occupee(initX+i,initY+i,echiquierG) != -1 )  //test si place ds trajectoire occupeee
	    	  {
	    		  libre = false;
	    	  }
	    	  else 
	    	  {
	    		  i++;
	    	  }
	      }
	    }
	  else if ( diff_a < 0 && diff_o < 0 )  //haut gauche
	      {
		  	int i = -1;
		  	while ( initX+i > finaleX && libre )
		  	{
		  		if ( position_occupee(initX+i,initY+i,echiquierG) != -1 )
		  		{
		  			libre = false;
		  		}
		  		else
		  		{
		    	i--;
		  		}
		  	}
		
	      }
	  	else if ( diff_a > 0 && diff_o < 0 )  //haut droite
	      {
	  		int i = 1, j = -1 ;
	  		while ( initX+i < finaleX && libre )
	  		{
	  			if ( position_occupee(initX+i,initY+j,echiquierG) != -1 )
	  			{
	  				libre = false;
	  			}
	  			else 
	  			{
	  				i++;
	  				j--;
	  			}
	  		}
	      
	      }
	  	else 
	  		if ( diff_a < 0 && diff_o > 0  )  // bas gauche
	  		{
	  			int i = -1, j = 1 ;
	  			while ( initX+i > finaleX  && libre )
	  			{
	  				if ( position_occupee(initX+i,initY+j,echiquierG) != -1 )
	  				{
	  					libre = false;
	  				}
	  				else
	  				{
	  					i--;
	  					j++;
	  				}
	  			}
	      }
	  return libre ;
	}
	
	/* ---------------------------- CAVALIER --------------------------- */
	public boolean deplace_cavalier(int initX, int initY,int finaleX, int finaleY, boolean echiquierG, boolean depl)
	{
		int diff_a = Math.abs(finaleX - initX);  // différence a plat
		int diff_o = Math.abs(finaleY - initY);  // difference en hauteur
		
		if ( (diff_a == 1 && diff_o == 2 ) || (diff_a == 1 && diff_o == -1 ) || (diff_a == -1 && diff_o == 2 ) || (diff_a == -1 && diff_o == -2 ) || (diff_a == -2 && diff_o == 1) || (diff_a  == -2 && diff_o == -1 ) || (diff_a == 2 && diff_o == 1 ) || (diff_a == 2 && diff_o == -1) )
		{
			/*traj cav valide*/
			if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == _trait)
			{ if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("une de vos pièces occupe cette position. Coup impossible !"); }}
			else
			{
				if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == -1 )
				{
					if (depl)
	    			{
						/*Deplacement CAVALIER*/
						  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
						  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
						  redessiner();
						  change_joueur();
	    			}
				  return true;
				}
				else
				{  
					if (echiquierG == _joueurs[(_trait+1)%2].get_piece(finaleX+1,finaleY+1).echiquierG())
					{
						if (depl)
						  {
							/*CAVALIER PREND*/
						  _joueurs[(_trait+1)%2].get_piece(finaleX +1, finaleY +1).delete();
		    			  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
		    			  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
		    			  redessiner();
		    			  change_joueur();
						}
						return true;
					}
					else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Pour pouvoir prendre, il faut que les pièces soient sur le même échiquier"); }}
				}
			}
		}
		else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Deplacement non valide");}}
		return false;
	}


	/* ----------------------------- ROI ----------------------------- */
	public boolean deplace_roi (int initX, int initY,int finaleX, int finaleY, boolean echiquierG, boolean depl)
	{
		int diff_a = Math.abs(finaleX - initX);  // différence a plat
		int diff_o = Math.abs(finaleY - initY);  // difference en hauteur
		
		if ( diff_a <= 1 && diff_o <= 1 && diff_a >= -1 && diff_o >= -1 )
		{
			if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == _trait)
			{ if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("une de vos pièces occupe cette position. Coup impossible !");}}
			else
			{
			  if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == -1 )
			  {
				  /*Deplacement ROI*/
				  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
				  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
				  redessiner();
				  change_joueur();
				  return true; 
			  }
			  else
			    {
				  if (echiquierG == _joueurs[(_trait+1)%2].get_piece(finaleX+1,finaleY+1).echiquierG())
				  {
					  /*ROI PREND*/
					  _joueurs[(_trait+1)%2].get_piece(finaleX +1, finaleY +1).delete();
					  _joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
					  _joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
					  redessiner();
					  change_joueur();

					  return true;
				  }
				  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Pour pouvoir prendre, il faut que les pièces soient sur le même échiquier"); }}
			    }  
			}
		  }
		  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Deplacement non valide");}}
		  return false;
		}



	/* ------------------------------ REINE ------------------------------ */
	public boolean deplace_reine(int initX, int initY,int finaleX, int finaleY, boolean echiquierG, boolean depl)
	{
		int diff_a = finaleX - initX;  // différence a plat
		int diff_o = finaleY - initY;  // difference en hauteur
		
		boolean deplaceR = false;
		
		System.out.println("Reine de x"+(initX+1)+" y"+(initY+1)+"  en x"+(finaleX+1)+" y"+(finaleY+1));

		if ( (diff_a+diff_o)==0 || (diff_a-diff_o)==0 )
		{
			if (test_trajectoire_fou_ok(diff_a,diff_o,initX+1, initY+1,finaleX+1, finaleY+1,echiquierG))
			{
				deplaceR = true;
			}
		}
		else if ( diff_a == 0 ^ diff_o == 0 )
		{
			if (test_trajectoire_tour_ok(diff_a,diff_o,initX+1, initY+1, finaleX+1, finaleY+1,echiquierG  ))
			{
				deplaceR = true;
			}
		}
	    //si pas d'obstacle
		if ( deplaceR )
	    {
		  //test si place non libre et piece adverse
			if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == _trait)
	    	{ if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("une de vos pièces occupe cette position. Coup impossible !");}}
			else
	    	{
				if (position_occupee(finaleX+1, finaleY+1, echiquierG ) == -1 )
		     	{
					if (depl)
	    			  {
						/*Deplacement REINE*/
						_joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
						_joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
						redessiner();
						change_joueur();
	    			  }
					return true;
				}
		     	else
		     	{
		     		 if (_joueurs[_trait].get_piece(initX+1, initY+1).echiquierG() == _joueurs[(_trait+1)%2].get_piece(finaleX+1,finaleY+1).echiquierG())
					  {
		     			if (depl)
						  {
			     			 /*REINE PREND*/
			     			_joueurs[(_trait+1)%2].get_piece(finaleX +1, finaleY +1).delete();
		    			  	_joueurs[_trait].set_pieces(recherche_indice_piece(initX+1, initY+1), finaleX+1, finaleY+1);
		    			  	_joueurs[_trait].get_piece(finaleX+1, finaleY+1).incr_nbDepl();
		    			  	redessiner();
		  		     		change_joueur();
						  }
	  		     		return true;
					  }
					  else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("Pour pouvoir prendre, il faut que les pièces soient sur le même échiquier"); }}
		     	}  
	    	}
	    }
		else { if (depl){fTmp.getError().setForeground(Color.RED); fTmp.getError().setText("La reine ne peut pas sauter une piece" ); }}
		return false;
	}
	
	
	/******** Fonction Drag'n Drop ********/
	
	/* Fonction Drag'n Drop des pieces */
	public void mouseDragged(MouseEvent e)
	{ 
		 
		JLabel temp = (JLabel) e.getSource(); /* creer une reference vers l'image sur laquelle on a clique */
		String c = temp.getName();
		
		if( (c == "n" && _trait == 1) || (c == "b" && _trait == 0) )
		{
			
			int coord_x = temp.getX() + e.getX() - 20; /* on recupere les coordonnees  */
			int coord_y = temp.getY() + e.getY() - 20; /* du deplacement de la piece */
			
			int coord_max_y;  /* coordonnees max et min a ne pas depasser  */
			int coord_max_x;  /* pour ne pas sortir de l'echiquier */
			int coord_min_y;
			int coord_min_x;
	
			if(echq == 1) /* Si on prend une piece de l'echiquier gauche */
			{
				coord_min_x = 100;
				coord_min_y = 50;
				coord_max_x = 380;
				coord_max_y = 330;	
			}
			else  /* Si on prend une piece de l'echiquier droit */
			{
				coord_min_x = 480;
				coord_min_y = 50;
				coord_max_x = 760;
				coord_max_y = 330;
			}
			
			temp.setBounds( /* redefinition de la position de la piece */
				/* conditions pour ne pas sortir du cadre */
				( coord_x > coord_max_x ? coord_max_x : (coord_x < coord_min_x ? coord_min_x : coord_x) ),
				( coord_y > coord_max_y ? coord_max_y : (coord_y < coord_min_y ? coord_min_y : coord_y) ),
				40,
				40
			); 
		}
	} 
	
	
	
	/* quand on appuie sur une piece */
	public void mousePressed(MouseEvent e)
	{
		JLabel temp = (JLabel) e.getSource(); /* reference sur la piece */
		String c = temp.getName();
		
		if( (c == "n" && _trait == 1) || (c == "b" && _trait == 0) )
		{
			coord_init_x = temp.getX(); // coordonnes de la piece
			coord_init_y = temp.getY();
			
			iy_init = (((coord_init_y + 20 -50)/40)%8);
			
			/* deux conditions qui determinent sur quel echiquier est la piece cliquee*/	
			if(coord_init_x > 100 && coord_init_x < 420) 
			{
				echq = 1;
				ix_init = (((coord_init_x + 20 -100)/40)%8);
			}
			else
			if(coord_init_x > 480 && coord_init_x < 800) 
			{
				echq = 2;
				ix_init = (((coord_init_x + 20 -480)/40)%8);
			}
			
			ptmp = _joueurs[_trait].get_piece(ix_init+1, iy_init+1);
			System.out.println("\n\nJoueur qui joue : " + _joueurs[_trait] + ", avec le trait : " + _trait);

			System.out.println("mousePressed - _joueurs["+_trait+"].get_piece("+(ix_init+1)+", "+(iy_init+1)+") = " + ptmp);

			/* On eleve l'index du calque, pour placer la piece au dessus de toute les autres */
			layeredPane.setLayer(temp, 10); 
		}
	}
	
	/* quand on relache la souris */
	public void mouseReleased(MouseEvent e)
	{
		JLabel temp = (JLabel) e.getSource(); /*reference*/
		String c = temp.getName();
		
		if( (c == "n" && _trait == 1) || (c == "b" && _trait == 0) )
		{
			int iy = (((temp.getY()+20-50)/40)%8);	/* +20 px : centre de la case, -100 -50 : marges haut et gauche, /40 : case de 40px, %8 : 8 cases */
			int ix = 0;
			int nx = 0;
			int ny = 0;
			
			System.out.println("echq"+echq);
			
			if (echq == 1)
			{
				ix = (((temp.getX()+20-100)/40)%8); /* indice x et y de la case relachee */
				nx = (int) p1[iy][ix].getX();	/* coordonnees de la case relachee */
				ny = (int) p1[iy][ix].getY();
			}
			else if (echq == 2)
			{
				ix = (((temp.getX()+20-480)/40)%8); /* indice x et y de la case relachee */
				nx = (int) p2[iy][ix].getX();	/* coordonnees de la case relachee */
				ny = (int) p2[iy][ix].getY();
				System.out.println("nx : "  + nx);
				System.out.println("ny : "  + ny);
				System.out.println("ix : "  + ix);
				System.out.println("iy : "  + iy);
				System.out.println(((temp.getX()+20-480)/40)%8);

			}
			
			if(deplacer_piece(ptmp, ix_init, iy_init, ix, iy))
			{
				System.out.println("toto");
				temp.setBounds( nx, ny, 40, 40 );  /* ajustement de la piece dans la case */
				
				fTmp.getJoueurJoue().setText("C'est au joueur "+get_trait_coul()+" de jouer");
				fTmp.getError().setForeground(Color.GREEN);
				fTmp.getError().setText("Allez y!");
			}
			else
			{
				temp.setBounds( coord_init_x, coord_init_y, 40, 40 );  /* ajustement de la piece dans la case */
			}
			layeredPane.setLayer(temp, 2, 1); /* index du calque par defaut */
		}
	}
	
	public void mouseEntered(MouseEvent e)
	{
		//System.out.println("mouseEntered");
	}
	
	public void mouseExited(MouseEvent e)
	{
		//System.out.println("mouseExited");
	}
	
	public void mouseClicked(MouseEvent e) 
	{}
	
	public void mouseMoved(MouseEvent e)
	{}
}